package cn.topevery.garden.wapi.controller;

import hw.topevery.basis.dal.logic.SysClassExtLogic;
import hw.topevery.basis.dal.logic.SysClassInTreeLogic;
import hw.topevery.basis.dal.logic.SysClassLogic;
import hw.topevery.basis.dal.logic.SysClassTreeDefineLogic;
import hw.topevery.basis.entity.BasisPrivilegeConst;
import hw.topevery.basis.entity.dto.ClassTree;
import hw.topevery.basis.entity.dto.SysClassDto;
import hw.topevery.basis.entity.fetch.ClassFetch;
import hw.topevery.basis.entity.po.*;
import hw.topevery.basis.runtime.UserRuntime;
import hw.topevery.framework.SystemConst;
import hw.topevery.framework.Utility;
import hw.topevery.framework.db.entity.DataPager;
import hw.topevery.framework.web.JsonResult;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@RequestMapping("/class")
@RestController
@Slf4j
public class ClassController extends BaseController {
    @Autowired
    private SysClassLogic sysClassLogic;

    @Autowired
    private SysClassExtLogic sysClassExtLogic;

    @Autowired
    private SysClassTreeDefineLogic sysClassTreeDefineLogic;

    @Autowired
    private SysClassInTreeLogic sysClassInTreeLogic;


    @PostMapping("/list")
    public JsonResult<DataPager<SysClass>> getClassList(ClassFetch para) {
        return JsonResult.ok(sysClassLogic.getPageListClass(para));
    }

    @ApiOperation("获取类型树形")
    @GetMapping("/tree")
    public JsonResult<List<ClassTree>> getClassTree() {
        return JsonResult.ok(sysClassLogic.getClassTree());
    }

    @ApiOperation("获取类型树形 我的默认部门创建")
    @GetMapping("/treeOwn")
    public JsonResult<List<ClassTree>> treeOwn() {
        List<ClassTree> result = new ArrayList<>();
        SysUser user = UserRuntime.getSysUser();
        if (ObjectUtils.isNotEmpty(user)) {
            result = sysClassLogic.getOwnClassTree(user.deptId);
        }
        return JsonResult.ok(result);
    }

    @GetMapping("/classInfo")
    public JsonResult<SysClassDto> getClassInfo(String classId) {
        return JsonResult.ok(sysClassLogic.getClassInfo(classId));
    }

    @PostMapping("/addOrEditClass")
    public JsonResult<Boolean> addOrEditClass(@RequestBody SysClassDto classEntity) {
        JsonResult<Boolean> result = new JsonResult<>();
        try {
            SysUser userObject = UserRuntime.getSysUser();
            if (userObject != null) {
                SysClass entity;
                SysClassExt entityExt;
                if (classEntity.classId.isEmpty()) {
                    entity = new SysClass();
                    String classId = Utility.uuidRandomString();
                    entity.classId = classId;

                    entity.createId = userObject.userId;
                    entity.createTime = LocalDateTime.now();

                    entity.updateId = userObject.userId;
                    entity.updateTime = LocalDateTime.now();

                    entityExt = new SysClassExt();
                    entityExt.classId = classId;
                } else {
                    entity = sysClassLogic.getEntityByDataId(classEntity.classId);
                    entity.updateId = getUser().userId;
                    entity.updateTime = LocalDateTime.now();

                    entityExt = sysClassExtLogic.getEntityByDataId(classEntity.classId);
                    if (ObjectUtils.isEmpty(entityExt)) {
                        entityExt = new SysClassExt();
                        entityExt.classId = classEntity.classId;
                    }
                }

                entityExt.limit = classEntity.getLimit() != null ? classEntity.getLimit() : 0;
                entityExt.unit = classEntity.getUnit();
                entityExt.deductMoney = classEntity.getDeductMoney() != null ? classEntity.getDeductMoney() : 0;
                entityExt.deductScore = classEntity.getDeductScore() != null ? classEntity.getDeductScore() : 0;

                if (ObjectUtils.isNotEmpty(entityExt.id) && entityExt.id > 0) {
                    sysClassExtLogic.update(userObject.userId, entityExt);
                } else {
                    sysClassExtLogic.save(userObject.userId, entityExt);
                }

                if (StringUtils.isBlank(classEntity.classPid) || StringUtils.isEmpty(classEntity.classPid)) {
                    classEntity.classPid = SystemConst.UUID_EMPTY_STRING;
                }
                entity.name = classEntity.name;
                entity.code = classEntity.code;
                entity.type = classEntity.type;
                entity.classPid = classEntity.classPid;
                entity.devCode = classEntity.devCode;
                entity.remark = classEntity.remark;
                entity.orderNum = classEntity.orderNum;
                if (ObjectUtils.isNotEmpty(entity.id) && entity.id > 0) {
                    sysClassLogic.update(userObject.userId, entity);
                } else {
                    sysClassLogic.save(userObject.userId, entity);
                }
                result.data = true;
            }
        } catch (Exception ignored) {
            result.setCode(400);
            result.success = false;
            result.msg = ignored.getMessage();
            log.error(ignored.getMessage(), ignored);
        }
        return result;
    }

    @PostMapping("/deleteClass")
    public JsonResult<?> deleteClass(String classId) {
        SysClass entity = sysClassLogic.getEntityByDataId(classId);
        entity.dbStatus = true;
        return JsonResult.ok(sysClassLogic.update(getUser().userId, entity));
    }

    @ApiOperation("获取自定义树")
    @GetMapping("/ctdList")
    public JsonResult<List<SysClassTreeDefine>> getCtdList() {
        return JsonResult.ok(sysClassTreeDefineLogic.getCtdList());
    }

    @ApiOperation("获取自定义树 我的默认部门创建")
    @GetMapping("/ctdOwnList")
    public JsonResult<List<SysClassTreeDefine>> ctdOwnList() {
        List<SysClassTreeDefine> result = new ArrayList<>();
        SysUser user = UserRuntime.getSysUser();
        if (ObjectUtils.isNotEmpty(user)) {
            result = sysClassTreeDefineLogic.getCtdList(user.deptId);
        }
        return JsonResult.ok(result);
    }

    @PostMapping("/addOrEditCtd")
    public JsonResult<Boolean> addOrEditCtd(@RequestBody SysClassTreeDefine ctdEntity) {
        JsonResult<Boolean> result = new JsonResult<>();
        try {
            SysUser userObject = UserRuntime.getSysUser();
            if (userObject != null) {
                SysClassTreeDefine entity;
                if (ctdEntity.classTreeId.isEmpty()) {
                    entity = new SysClassTreeDefine();
                    String ctdId = Utility.uuidRandomString();
                    entity.classTreeId = ctdId;
                    entity.createId = userObject.userId;
                    entity.createTime = LocalDateTime.now();

                } else {
                    entity = sysClassTreeDefineLogic.getEntityByDataId(ctdEntity.classTreeId);
                }

                entity.name = ctdEntity.name;
                entity.desc = ctdEntity.desc;
                entity.updateId = userObject.userId;
                entity.updateTime = LocalDateTime.now();
                if (ObjectUtils.isNotEmpty(entity.id) && entity.id > 0) {
                    result.data = sysClassTreeDefineLogic.update(userObject.userId, entity);
                } else {
                    result.data = sysClassTreeDefineLogic.save(userObject.userId, entity);
                }
            }
        } catch (Exception ignored) {
            result.setCode(400);
            result.success = false;
            result.msg = ignored.getMessage();
            log.error(ignored.getMessage(), ignored);
        }
        return result;
    }

    @GetMapping("/ctdInfo")
    public Object getCtdInfo(String ctdId) {
        JsonResult<SysClassTreeDefine> result = new JsonResult<>();
        try {
            result.data = sysClassTreeDefineLogic.getEntityByDataId(ctdId);
        } catch (Exception ignored) {
            result.setCode(400);
            result.success = false;
            result.msg = ignored.getMessage();
            log.error(ignored.getMessage(), ignored);
        }
        return result;
    }

    @PostMapping("/classPageList")
    public JsonResult<DataPager<SysClassDto>> getClassDataPagerList(ClassFetch para) {
        JsonResult<DataPager<SysClassDto>> result = new JsonResult<>(true);
        try {
            result.data = sysClassInTreeLogic.getClassPageList(para);
        } catch (Exception ignored) {
            result.setCode(400);
            result.success = false;
            result.msg = ignored.getMessage();
            log.error(ignored.getMessage(), ignored);
        }
        return result;
    }

    //ClassInTree操作
    @ApiOperation("获取待调入的类型树")
    @GetMapping("/getNotInTreeList")
    public Object getNotInTreeList(String treeId) {
        JsonResult<List<ClassTree>> result = new JsonResult<>(true);
        try {
            result.data = sysClassInTreeLogic.getClassNoInTreeByClassId(treeId, SystemConst.UUID_EMPTY_STRING);
        } catch (Exception ignored) {
            result.setCode(400);
            result.success = false;
            result.msg = ignored.getMessage();
            log.error(ignored.getMessage(), ignored);
        }
        return result;
    }

    @ApiOperation("获取已调入的类型树")
    @GetMapping("/getInTreeList")
    public Object getInTreeList(String treeId) {
        JsonResult<List<ClassTree>> result = new JsonResult<>(true);
        try {
            result.data = sysClassInTreeLogic.getClassInTreeByTreeId(treeId, SystemConst.UUID_EMPTY_STRING);
        } catch (Exception ignored) {
            result.setCode(400);
            result.success = false;
            result.msg = ignored.getMessage();
            log.error(ignored.getMessage(), ignored);
        }
        return result;
    }

    @ApiOperation("调入类型树")
    @PostMapping("/addCT")
    public JsonResult<Boolean> addCT(@RequestBody ClassFetch para) {
        JsonResult<Boolean> result = new JsonResult<>();
        try {
            SysUser userObject = UserRuntime.getSysUser();
            if (userObject != null) {
                SysClass sysClass = sysClassLogic.getEntityByDataId(para.getClassId());
                if (para.getIsHaveChild()) {
                    List<SysClass> classList = new ArrayList<>();
                    findAllClass(classList, para.getClassId());
                    if (classList.size() > 0) {
                        for (SysClass classItem : classList) {
                            SysClassInTree cit = new SysClassInTree();
                            cit.classPid = classItem.classPid;
                            cit.classTreeId = para.getTreeId();
                            cit.classId = classItem.classId;
                            cit.name = classItem.name;
                            cit.code = classItem.code;
                            cit.type = classItem.type;
                            cit.createTime = LocalDateTime.now();
                            cit.createId = userObject.userId;
                            cit.updateTime = LocalDateTime.now();
                            cit.updateId = userObject.userId;

                            sysClassInTreeLogic.save(userObject.userId, cit);
                        }
                    }
                }
                SysClassInTree cit = new SysClassInTree();
                cit.classPid = sysClass.classPid;
                cit.classTreeId = para.getTreeId();
                cit.classId = sysClass.classId;
                cit.name = sysClass.name;
                cit.code = sysClass.code;
                cit.type = sysClass.type;
                cit.createTime = LocalDateTime.now();
                cit.createId = userObject.userId;
                cit.updateTime = LocalDateTime.now();
                cit.updateId = userObject.userId;
                sysClassInTreeLogic.save(userObject.userId, cit);
            }
        } catch (Exception ignored) {
            result.setCode(400);
            result.success = false;
            result.msg = ignored.getMessage();
            log.error(ignored.getMessage(), ignored);
        }
        return result;
    }

    @ApiOperation("调出类型树")
    @PostMapping("/delCT")
    public JsonResult<Boolean> delCT(@RequestBody ClassFetch para) {
        JsonResult<Boolean> result = new JsonResult<>();
        try {
            SysUser userObject = UserRuntime.getSysUser();
            if (userObject != null) {
                if (para.getClassList().size() > 0) {
                    for (SysClassDto itemClass : para.getClassList()) {
                        List<SysClassInTree> citList = new ArrayList<>();
                        findAllCIT(citList, itemClass.classId, para.getTreeId());
                        ClassFetch pram = new ClassFetch();
                        pram.setTreeId(para.getTreeId());
                        pram.setClassId(itemClass.classId);
                        List<SysClassInTree> cList = sysClassInTreeLogic.getCitList(pram);
                        citList.addAll(cList);
                        if (citList.size() > 0) {
                            for (SysClassInTree item : citList) {
                                item.dbStatus = true;
                                sysClassInTreeLogic.update(userObject.userId, item);
                            }
                        }

                    }
                }
            }
        } catch (Exception ignored) {
            result.setCode(400);
            result.success = false;
            result.msg = ignored.getMessage();
            log.error(ignored.getMessage(), ignored);
        }
        return result;
    }


    private void findAllClass(List<SysClass> dataList, String classPId) {
        ClassFetch searchParam = new ClassFetch();
        searchParam.setParentId(classPId);
        List<SysClass> cList = sysClassLogic.getListClass(searchParam);
        if (cList.size() > 0) {
            dataList.addAll(cList);
            cList.forEach(x -> findAllClass(dataList, x.classId));
        }
    }

    private void findAllCIT(List<SysClassInTree> dataList, String classPId, String treeId) {
        ClassFetch pram = new ClassFetch();
        pram.setTreeId(treeId);
        pram.setParentId(classPId);
        List<SysClassInTree> cList = sysClassInTreeLogic.getCitList(pram);
        if (cList.size() > 0) {
            dataList.addAll(cList);
            cList.forEach(x -> findAllCIT(dataList, x.classId, treeId));
        }
    }
}
